"""
监控服务 - 商品监控和任务管理
"""

from datetime import datetime, timedelta

# 北京时间函数
def get_beijing_now():
    """获取北京时间（UTC+8）"""
    return datetime.utcnow() + timedelta(hours=8)
from typing import List, Optional, Dict, Any
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
import redis.asyncio as redis

from app.models.monitor import Monitor, MonitorStatus, MonitorType
from app.schemas.monitor import MonitorCreate, MonitorUpdate


class MonitorService:
    """监控服务类"""
    
    def __init__(self):
        self.redis_client = None
    
    async def create_monitor(self, db: AsyncSession, user_id: int, monitor_data: MonitorCreate) -> Monitor:
        """创建监控任务"""
        # 检查用户余额是否足够
        from app.services.balance_service import BalanceService
        balance_service = BalanceService()
        
        if not await balance_service.check_balance(db, user_id, 1):
            raise ValueError("余额不足，无法创建监控任务")
        
        # 创建监控任务
        monitor = Monitor(
            user_id=user_id,
            monitor_type=monitor_data.monitor_type,
            name=monitor_data.name,
            description=monitor_data.description,
            conditions=monitor_data.conditions.dict(),
            status=MonitorStatus.PENDING,
            is_active=True,
            duration_hours=monitor_data.duration_hours or 24,
            expires_at=get_beijing_now() + timedelta(hours=monitor_data.duration_hours or 24)
        )
        
        db.add(monitor)
        await db.commit()
        await db.refresh(monitor)
        
        # 扣除余额
        await balance_service.deduct_balance(db, user_id, 1, f"创建监控任务: {monitor.name}")
        
        return monitor
    
    async def get_user_monitors(self, db: AsyncSession, user_id: int) -> List[Monitor]:
        """获取用户的监控任务"""
        result = await db.execute(
            select(Monitor).where(
                and_(Monitor.user_id == user_id, Monitor.is_active == True)
            ).order_by(Monitor.created_at.desc())
        )
        return result.scalars().all()
    
    async def get_monitor_by_id(self, db: AsyncSession, monitor_id: int, user_id: int) -> Optional[Monitor]:
        """根据ID获取监控任务"""
        result = await db.execute(
            select(Monitor).where(
                and_(
                    Monitor.id == monitor_id,
                    Monitor.user_id == user_id,
                    Monitor.is_active == True
                )
            )
        )
        return result.scalar_one_or_none()
    
    async def update_monitor(self, db: AsyncSession, monitor_id: int, user_id: int, 
                           monitor_data: MonitorUpdate) -> Optional[Monitor]:
        """更新监控任务"""
        monitor = await self.get_monitor_by_id(db, monitor_id, user_id)
        if not monitor:
            return None
        
        # 更新字段
        for field, value in monitor_data.dict(exclude_unset=True).items():
            setattr(monitor, field, value)
        
        monitor.updated_at = get_beijing_now()
        await db.commit()
        await db.refresh(monitor)
        return monitor
    
    async def delete_monitor(self, db: AsyncSession, monitor_id: int, user_id: int) -> bool:
        """删除监控任务"""
        monitor = await self.get_monitor_by_id(db, monitor_id, user_id)
        if not monitor:
            return False
        
        monitor.is_active = False
        monitor.updated_at = get_beijing_now()
        await db.commit()
        return True
    
    async def check_expired_monitors(self, db: AsyncSession) -> List[Monitor]:
        """检查过期的监控任务"""
        result = await db.execute(
            select(Monitor).where(
                and_(
                    Monitor.is_active == True,
                    Monitor.expires_at < get_beijing_now()
                )
            )
        )
        expired_monitors = result.scalars().all()
        
        # 标记为过期
        for monitor in expired_monitors:
            monitor.is_active = False
            monitor.status = MonitorStatus.EXPIRED
            monitor.updated_at = get_beijing_now()
        
        await db.commit()
        return expired_monitors
    
    async def get_active_monitors(self, db: AsyncSession) -> List[Monitor]:
        """获取所有活跃的监控任务"""
        result = await db.execute(
            select(Monitor).where(
                and_(
                    Monitor.is_active == True,
                    Monitor.expires_at > get_beijing_now()
                )
            )
        )
        return result.scalars().all()
